﻿using System;
using System.Collections.Generic;
//using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using SAD.Common.Models;
using SAD.ShowClient.ShowItems;
using SAD.ClientLogic;
using SAD.ShowNodeClientLib;

namespace SAD.ShowClient.Controls
{
    /// <summary>
    /// InfoPanel.xaml 的交互逻辑
    /// </summary>
    public partial class InfoPanel : UserControl
    {
        private object syncAllData = new object();

        private System.Threading.Thread m_AutoInfoScrollThread;

        private List<ShowItemBase> m_AllInfoByOrder = new List<ShowItemBase>();

        private Dictionary<long, ShowItemBase> m_AllInfoByID = new Dictionary<long, ShowItemBase>();

        private List<ShowItemBase> m_WaitClearInfos = new List<ShowItemBase>();

        private Queue<ShowItemBase> m_WaitShowQueueInfo = new Queue<ShowItemBase>();

        public int CategoryID { get; private set; }

        public InfoPanel(int categoryID)
        {
            InitializeComponent();

            this.CategoryID = categoryID;
            this.Name = string.Format("InfoPanel_{0}", this.CategoryID);
        }

        public void AddInfo(Info_Data info)
        {
            ShowItems.ucNormalText si = new ShowItems.ucNormalText(info);
            //si.SetBinding(Canvas.WidthProperty, new Binding("ElementName=" + this.Name + ", Path=Width"));
            //si.SetBinding(Canvas.HeightProperty, new Binding("ElementName=" + this.Name + ", Path=Height"));

            AddElement(si, true);
        }

        private void AddElement(ShowItemBase e, bool newInfo)
        {
            this.Dispatcher.Invoke(new System.Threading.WaitCallback(delegate(object obj)
            {
                lock (syncAllData)
                {
                    //加入新信息元素至m_InfoByOrders
                    if (newInfo && !this.m_AllInfoByOrder.Contains(e) && this.m_AllInfoByID.ContainsKey(e.InfoData.ID))
                    {
                        this.m_AllInfoByOrder.Add(e);
                        this.m_AllInfoByID.Add(e.InfoData.ID, e);
                    }

                    //清理超出m_MaxInfoNumber的
                    int needClearNum = (m_AllInfoByOrder.Count - MainActivator.Current.InfoMaxNumber);
                    if (m_AllInfoByOrder.Count > 0)
                    {

                        for (int i = 0; i < needClearNum; i++)
                        {
                            ShowItemBase clearTarget = m_AllInfoByOrder[0];
                            m_AllInfoByOrder.Remove(clearTarget);
                            if (m_WaitShowQueueInfo.Contains(clearTarget))
                            {
                                m_WaitClearInfos.Add(clearTarget);
                            }
                            else
                            {
                                m_InfoPanel.Children.Remove(clearTarget);
                            }
                        }

                    }

                    //清除超出分页的item，放入队列
                    int needRemoveNum = (m_InfoPanel.Children.Count - MainActivator.Current.InfoPageSize) + 1;
                    if (needRemoveNum > 1)
                    {

                        for (int i = 0; i < needRemoveNum; i++)
                        {
                            ShowItemBase removeElement = (ShowItemBase)m_InfoPanel.Children[m_InfoPanel.Children.Count - 1];
                            if (removeElement != null)
                            {
                                m_WaitShowQueueInfo.Enqueue(removeElement);
                            }
                            m_InfoPanel.Children.Remove(removeElement);
                        }
                    }

                    //
                    try
                    {
                        m_InfoPanel.Children.Insert(0, e);
                    }
                    catch (Exception ex)
                    {
                        Exception xxx = ex;
                    }
                }

            }), new object());
        }

        public void RemoveInfo(long infoID)
        {
            if(!m_AllInfoByID.ContainsKey(infoID))
            {
                return;
            }

            ShowItemBase removeItem = m_AllInfoByID[infoID];
            RemoveElement(removeItem);
        }
        private void RemoveElement(ShowItemBase e)
        {
            lock (syncAllData)
            {
                if (m_InfoPanel.Children.Contains(e))
                {
                    m_InfoPanel.Children.Remove(e);
                }
                else if (m_WaitShowQueueInfo.Contains(e))
                {
                    m_WaitClearInfos.Add(e);
                }

                if (m_AllInfoByOrder.Contains(e))
                {
                    m_AllInfoByOrder.Remove(e);
                }
                m_AllInfoByID.Remove(e.InfoData.ID);
            }
        }
        
        public void Start()
        {
            //初始化数据
            Info_Data[] infos = MainActivator.Current.InfosByCategoryID[this.CategoryID];
            lock (syncAllData)
            {
                foreach (Info_Data info in infos)
                {
                    ShowItems.ucNormalText si = new ShowItems.ucNormalText(info);

                    this.m_AllInfoByOrder.Add(si);
                    this.m_AllInfoByID.Add(si.InfoData.ID, si);
                    this.m_WaitShowQueueInfo.Enqueue(si);
                    
                }
            }

            m_AutoInfoScrollThread = new System.Threading.Thread(new System.Threading.ParameterizedThreadStart(InfoScroll));
            m_AutoInfoScrollThread.Start();
        }

        public void Stop()
        {
            m_AutoInfoScrollThread.Abort();
            m_AutoInfoScrollThread = null;

            lock (syncAllData)
            {
                m_AllInfoByOrder.Clear();
                m_AllInfoByID.Clear();
                m_WaitClearInfos.Clear();
                m_WaitShowQueueInfo.Clear();
                m_InfoPanel.Children.Clear();
            }
        }

        private void InfoScroll(object nullobj)
        {
            while (true)
            {
                if (m_WaitShowQueueInfo.Count > 0)
                {
                    lock (syncAllData)
                    {
                        this.Dispatcher.Invoke(new System.Threading.WaitCallback(delegate(object arg)
                        {
                            for (int i = 0; i < m_InfoPanel.Children.Count; i++)
                            {
                                m_WaitShowQueueInfo.Enqueue((ShowItemBase)m_InfoPanel.Children[i]);
                            }
                            m_InfoPanel.Children.Clear();
                        }), new object());


                        for (int i = 0; m_WaitShowQueueInfo.Count > 0 && i < MainActivator.Current.InfoPageSize; i++)
                        {
                            ShowItemBase addElement = m_WaitShowQueueInfo.Dequeue();
                            this.Dispatcher.Invoke(new System.Threading.WaitCallback(delegate(object arg)
                            {
                                ShowItemBase x = (ShowItemBase)arg;
                                m_InfoPanel.Children.Add(x);
                            }), addElement);
                        }

                        //ShowItemBase addElement = m_WaitShowQueueInfo.Dequeue();
                        //if (addElement == null)
                        //{
                        //    return;
                        //}
                        //if (!m_WaitClearInfos.Contains(addElement))
                        //{
                        //    AddElement(addElement, false);
                        //}
                        //else
                        //{
                        //    m_WaitClearInfos.Remove(addElement);
                        //    continue;
                        //}
                    }
                }
                System.Threading.Thread.Sleep(MainActivator.Current.InfoAutoScrollTimeSpan);
            }
        }
    }
}